//@author A0096509U
#include "StringParser.h"

StringParser::StringParser() {
	clearInfoString();
}

void StringParser::splitString(string allInfo) {
	assert(!allInfo.empty());
	clearInfoString();
	int numOfOpenBracket, numOfClosedBracket;
	numOfOpenBracket = INITIAL_VALUE;
	numOfClosedBracket = INITIAL_VALUE;
	char previousBracket = CLOSED_SQUARE_BRACKET;
	char previousChar = CLOSED_SQUARE_BRACKET;
	string check = allInfo;

	while (allInfo[INITIAL_VALUE] != WHITE_SPACE && !allInfo.empty()) {
		_infoString[INITIAL_VALUE] = _infoString[INITIAL_VALUE] + allInfo[INITIAL_VALUE];
		allInfo.erase(allInfo.begin());
	}
	if (!allInfo.empty() && allInfo[INITIAL_VALUE] == WHITE_SPACE) {
		allInfo.erase(allInfo.begin());
	}
	int i = ONE_STARTING_VALUE;
	while(!allInfo.empty()) {
		if (i == NUM_OF_INFO) {
			throw INVALID_REQUEST;
		}
		if (allInfo[INITIAL_VALUE] == OPEN_SQUARE_BRACKET) {
			if (previousBracket == OPEN_SQUARE_BRACKET || previousChar != CLOSED_SQUARE_BRACKET) {
				throw INVALID_REQUEST;
			} else {
				previousBracket = OPEN_SQUARE_BRACKET;
			}
			numOfOpenBracket++;
		} else if (allInfo[INITIAL_VALUE] == CLOSED_SQUARE_BRACKET) {
			if (previousBracket == CLOSED_SQUARE_BRACKET) {
				throw INVALID_REQUEST;
			} else {
				previousBracket = CLOSED_SQUARE_BRACKET;
				i++;
				numOfClosedBracket++;
			}
		} else {
			_infoString[i] = _infoString[i] + allInfo[INITIAL_VALUE];
		}
		previousChar = allInfo[INITIAL_VALUE];
		allInfo.erase(allInfo.begin());
	}
	size_t found;
	found = check.find(BLOCK_FUNCTION);
	if ((found != string::npos || check == BLOCK_FUNCTION_TWO) && _infoString[INITIAL_VALUE] != COMMAND_SEARCH) {
		throw INVALID_USE_OF_BLOCK;
	}
	if (numOfOpenBracket != numOfClosedBracket || previousBracket == OPEN_SQUARE_BRACKET || 
	   (numOfOpenBracket > INITIAL_VALUE && previousChar != CLOSED_SQUARE_BRACKET)) {
		throw INVALID_REQUEST;
	}
	if ((_infoString[INITIAL_VALUE] == COMMAND_ADD && numOfOpenBracket != SIX) ||
		(_infoString[INITIAL_VALUE] == COMMAND_DELETE && numOfOpenBracket != ONE) ||
		(_infoString[INITIAL_VALUE] == COMMAND_F_DELETE && numOfOpenBracket != ONE) ||
		(_infoString[INITIAL_VALUE] == COMMAND_EDIT && numOfOpenBracket != SEVEN) ||
		(_infoString[INITIAL_VALUE] == COMMAND_F_EDIT && numOfOpenBracket != SEVEN) ||
		(_infoString[INITIAL_VALUE] == COMMAND_VIEW && numOfOpenBracket != ONE) ||
		(_infoString[INITIAL_VALUE] == COMMAND_MARK && numOfOpenBracket != ONE) ||
		(_infoString[INITIAL_VALUE] == COMMAND_UNMARK && numOfOpenBracket != ONE) ||
		(_infoString[INITIAL_VALUE] == COMMAND_BLOCK && numOfOpenBracket != SIX) ||
		(_infoString[INITIAL_VALUE] == COMMAND_CONFIRM && numOfOpenBracket != ONE) ||
		(_infoString[INITIAL_VALUE] == COMMAND_SEARCH && numOfOpenBracket != ONE) ||
		(_infoString[INITIAL_VALUE] == COMMAND_UNDO && numOfOpenBracket != INITIAL_VALUE) ||
		(_infoString[INITIAL_VALUE] == COMMAND_CLEAR && numOfOpenBracket != INITIAL_VALUE)) {
		throw INVALID_REQUEST;
	}

	generateEmptyField();
	return;
}

void StringParser::generateEmptyField() {
	for (int i = INITIAL_VALUE; i < NUM_OF_INFO;i++) {
		if (i == INITIAL_VALUE && _infoString[i] == SEARCH) {
			if (_infoString[i + SHIFT_INDEX_BY_ONE].empty()) {
				i++;
			}
		} else if (_infoString[i].empty() || 
				   _infoString[i] == CATEGORY || 
				   _infoString[i] == VENUE || 
				   _infoString[i] == ACTIVITY || 
				   _infoString[i] == TIME_START || 
				   _infoString[i] == TIME_END || 
				   _infoString[i] == DATE_FIELD) {
			_infoString[i] = EMPTY_FIELD;
		}
	}
	return;
}

string StringParser::contentateFields(string activity, string venue, string timeStart, string timeEnd, string category, string date) {
	ostringstream contentatedFields;
	if (activity == EMPTY_FIELD) {
		activity = ACTIVITY;
	}
	if (venue == EMPTY_FIELD) {
		venue = VENUE;
	}
	if (timeStart == EMPTY_FIELD) {
		timeStart = TIME_START;
	}
	if (timeEnd == EMPTY_FIELD) {
		timeEnd = TIME_END;
	}
	if (category == EMPTY_FIELD) {
		category = CATEGORY;
	}
	if (date == EMPTY_FIELD) {
		date = DATE_FIELD;
	}
	contentatedFields << OPEN_SQUARE_BRACKET << activity << 
	CLOSED_SQUARE_BRACKET << OPEN_SQUARE_BRACKET << venue << 
	CLOSED_SQUARE_BRACKET << OPEN_SQUARE_BRACKET << timeStart << 
	CLOSED_SQUARE_BRACKET << OPEN_SQUARE_BRACKET << timeEnd << 
	CLOSED_SQUARE_BRACKET << OPEN_SQUARE_BRACKET << category << 
	CLOSED_SQUARE_BRACKET << OPEN_SQUARE_BRACKET << date << CLOSED_SQUARE_BRACKET;
	return contentatedFields.str();
}

string StringParser::getInfoNumber(int index) {
	assert(index < NUM_OF_INFO);
	return _infoString[index];
}

void StringParser::clearInfoString() {
	for (int i = INITIAL_VALUE; i < NUM_OF_INFO; i++) {
		_infoString[i].clear();
	}
	return;
}